package com.mce.nebula.service;

import com.mce.nebula.dto.*;
import com.mce.nebula.entity.Enterprise;
import com.mce.nebula.entity.Team;
import com.mce.nebula.entity.User;
import com.mce.nebula.repository.UserRepository;
import com.mce.nebula.security.JwtUtils;
import com.mce.nebula.security.UserDetailsImpl;
import com.mce.nebula.util.ValidationUtils;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Optional;

/**
 * 认证服务，对应Python的认证相关功能
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class AuthService {
    
    private final AuthenticationManager authenticationManager;
    private final UserRepository userRepository;
    private final JwtUtils jwtUtils;
    private final PasswordEncoder passwordEncoder;
    private final EnterpriseService enterpriseService;
    private final TeamService teamService;
    private final CaptchaService captchaService;
    
    /**
     * 用户登录
     */
    public LoginResponse login(LoginRequest loginRequest) {
        try {
            // 认证用户
            Authentication authentication = authenticationManager.authenticate(
                new UsernamePasswordAuthenticationToken(
                    loginRequest.getNickName(), 
                    loginRequest.getPassword()
                )
            );
            
            // 获取用户信息
            User user = userRepository.findByNickName(loginRequest.getNickName())
                .orElseThrow(() -> new BadCredentialsException("用户不存在"));
            
            // 检查用户是否激活
            if (!user.getIsActive()) {
                throw new BadCredentialsException("用户未激活");
            }
            
            // 生成JWT Token
            String token = jwtUtils.generateToken(
                user.getNickName(), 
                user.getId(), 
                user.getEnterpriseId()
            );
            
            // 返回登录响应
            return new LoginResponse(
                token,
                user.getId(),
                user.getNickName(),
                user.getEmail(),
                user.getRealName(),
                user.getEnterpriseId(),
                user.getSysAdmin()
            );
            
        } catch (AuthenticationException e) {
            log.error("Authentication failed for user: {}", loginRequest.getNickName(), e);
            throw new BadCredentialsException("用户名或密码错误");
        }
    }
    
    /**
     * 用户注册
     */
    @Transactional
    public LoginResponse register(UserRegisterRequest request) {
        // 规范化用户名
        String normalizedUserName = ValidationUtils.normalizeNameForK8sNamespace(request.getUserName());
        
        // 验证用户名格式
        if (!ValidationUtils.isStandardUsername(normalizedUserName)) {
            throw new IllegalArgumentException("用户名只可以使用小写英文字母、数字、下划线、中划线");
        }
        
        // 检查敏感词
        if (ValidationUtils.isSensitiveWord(normalizedUserName)) {
            throw new IllegalArgumentException("不允许的用户名");
        }
        
        // 验证密码一致性
        if (!request.getPassword().equals(request.getConfirmPassword())) {
            throw new IllegalArgumentException("两次输入的密码不一致");
        }
        
        // 验证验证码
//        if (request.getCaptchaCode() == null || request.getCaptchaCode().isEmpty()) {
//            throw new IllegalArgumentException("验证码不能为空");
//        }
        
        // 检查用户是否已存在
        if (userRepository.existsByNickName(normalizedUserName)) {
            throw new IllegalArgumentException("该用户名已存在");
        }
        
        if (userRepository.existsByEmail(request.getEmail())) {
            throw new IllegalArgumentException("邮件地址已被注册");
        }
        
        // 检查手机号是否已存在
//        if (request.getPhone() != null && !request.getPhone().trim().isEmpty()) {
//            if (userRepository.existsByPhone(request.getPhone())) {
//                throw new IllegalArgumentException("手机号已存在");
//            }
//        }
        
        // 创建新用户
        User user = new User();
        user.setNickName(normalizedUserName);
        user.setEmail(request.getEmail());
        user.setPassword(passwordEncoder.encode(request.getPassword()));
        user.setRealName(request.getRealName());
        user.setPhone(request.getPhone());
        user.setIsActive(true);
        user.setCreateTime(LocalDateTime.now());
        
        user = userRepository.save(user);
        
        // 获取或创建企业
        Enterprise enterprise = getOrCreateEnterprise(request.getEnterName());
        user.setEnterpriseId(enterprise.getEnterpriseId());
        user = userRepository.save(user);
        
        // 如果是第一个用户，设置为系统管理员
        if (userRepository.count() == 1) {
            user.setSysAdmin(true);
            user = userRepository.save(user);
        }
        
        // 创建用户在企业的权限
        enterpriseService.makeUserAsAdminForEnterprise(user.getId(), enterprise.getEnterpriseId());
        
        // 创建团队
        Team team = createTeamForUser(user, enterprise, normalizedUserName);
        
        // 如果是邀请注册，处理团队关联逻辑
        if ("invitation".equals(request.getRegisterType()) && request.getValue() != null) {
            // 这里应该处理邀请注册逻辑
            // 添加用户到指定团队
            log.info("Processing invitation registration for user: {} to team: {}", 
                    user.getId(), request.getValue());
        }
        
        // 生成JWT Token
        String token = jwtUtils.generateToken(
            user.getNickName(), 
            user.getId(), 
            user.getEnterpriseId()
        );
        
        log.info("用户注册成功: {} (ID: {})", user.getNickName(), user.getId());
        
        return new LoginResponse(
            token,
            user.getId(),
            user.getNickName(),
            user.getEmail(),
            user.getRealName(),
            user.getEnterpriseId(),
            user.getSysAdmin()
        );
    }
    
    /**
     * 获取或创建企业
     */
    private Enterprise getOrCreateEnterprise(String enterName) {
        Optional<Enterprise> existingEnterprise = enterpriseService.getEnterpriseFirst();
        
        if (existingEnterprise.isPresent()) {
            return existingEnterprise.get();
        }
        
        // 创建新企业
        return enterpriseService.createEnterprise(null, enterName);
    }
    
    /**
     * 为用户创建团队
     */
    private Team createTeamForUser(User user, Enterprise enterprise, String teamName) {
        // 检查是否使用SAAS模式
        boolean useSaas = System.getenv("USE_SAAS") != null;
        
        if (useSaas) {
            // SAAS模式：创建以用户名为团队名的团队
            Team team = teamService.createTeam(user, enterprise.getEnterpriseId(), teamName);
            
            // 设置默认资源限制：4 Core 8 GB
            TeamService.ResourceLimit limit = new TeamService.ResourceLimit(8192, 4000, 0);
            teamService.setTenantResourceLimit(enterprise.getEnterpriseId(), "default-region", 
                                             team.getTenantName(), limit);
            
            return team;
        } else {
            // 普通模式：创建默认团队
            return teamService.createTeam(user, enterprise.getEnterpriseId(), 
                                        List.of("rainbond"), "", "default", "");
        }
    }
    
    /**
     * 发送密码重置邮件
     */
    public void sendResetEmail(String email) {
        User user = userRepository.findByEmail(email)
            .orElseThrow(() -> new IllegalArgumentException("用户不存在"));
        
        // 这里应该实现邮件发送逻辑
        // 生成重置链接并发送邮件
        log.info("Sending reset email to: {}", email);
    }
    
    /**
     * 重置密码
     */
    @Transactional
    public void resetPassword(String tag, PasswordResetRequest request) {
        // 验证密码一致性
        if (!request.getPassword().equals(request.getPasswordRepeat())) {
            throw new IllegalArgumentException("两次输入的密码不一致");
        }
        
        // 这里应该验证tag的有效性和过期时间
        // 简化处理，实际应该解析tag获取用户信息
        log.info("Resetting password with tag: {}", tag);
        
        // 更新密码
        // User user = getUserFromTag(tag);
        // user.setPassword(passwordEncoder.encode(request.getPassword()));
        // userRepository.save(user);
    }
    
    /**
     * 修改密码
     */
    @Transactional
    public void changePassword(ChangePasswordRequest request) {
        UserDetailsImpl currentUser = getCurrentUser();
        
        // 验证原密码
        User user = userRepository.findById(currentUser.getId().longValue())
            .orElseThrow(() -> new IllegalArgumentException("用户不存在"));
        
        if (!passwordEncoder.matches(request.getPassword(), user.getPassword())) {
            throw new IllegalArgumentException("原密码错误");
        }
        
        // 验证新密码一致性
        if (!request.getNewPassword().equals(request.getNewPassword2())) {
            throw new IllegalArgumentException("两次输入的新密码不一致");
        }
        
        // 验证新旧密码不同
        if (request.getPassword().equals(request.getNewPassword())) {
            throw new IllegalArgumentException("新旧密码不能相同");
        }
        
        // 更新密码
        user.setPassword(passwordEncoder.encode(request.getNewPassword()));
        userRepository.save(user);
    }
    
    /**
     * 获取用户详情
     */
    public UserDetailsResponse getUserDetails(String teamName) {
        UserDetailsImpl currentUser = getCurrentUser();
        User user = userRepository.findById(currentUser.getId().longValue())
            .orElseThrow(() -> new IllegalArgumentException("用户不存在"));
        
        UserDetailsResponse response = new UserDetailsResponse();
        response.setUserId(user.getId());
        response.setUserName(user.getNickName());
        response.setRealName(user.getRealName());
        response.setLogo(user.getLogo());
        response.setEmail(user.getEmail());
        response.setEnterpriseId(user.getEnterpriseId());
        response.setPhone(user.getPhone());
//        response.setSysAdmin(user.getSysAdmin());
        
        // 这里应该设置更多详细信息，如团队信息、权限等
        // 简化处理
        
        return response;
    }
    
    /**
     * 更新用户信息
     */
    @Transactional
    public void updateUserDetails(UserDetailsResponse request) {
        UserDetailsImpl currentUser = getCurrentUser();
        User user = userRepository.findById(currentUser.getId().longValue())
            .orElseThrow(() -> new IllegalArgumentException("用户不存在"));
        
        user.setRealName(request.getRealName());
        user.setEmail(request.getEmail());
        user.setLogo(request.getLogo());
        
        userRepository.save(user);
    }
    
    /**
     * 获取用户收藏
     */
    public List<UserFavoriteResponse> getUserFavorites() {
        UserDetailsImpl currentUser = getCurrentUser();
        // 这里应该从数据库获取用户收藏
        // 简化处理，返回空列表
        return List.of();
    }
    
    /**
     * 添加用户收藏
     */
    @Transactional
    public void addUserFavorite(UserFavoriteRequest request) {
        UserDetailsImpl currentUser = getCurrentUser();
        // 这里应该保存用户收藏到数据库
        log.info("Adding favorite for user: {}, name: {}, url: {}", 
                currentUser.getId(), request.getName(), request.getUrl());
    }
    
    /**
     * 更新用户收藏
     */
    @Transactional
    public void updateUserFavorite(Integer favoriteId, UserFavoriteRequest request) {
        UserDetailsImpl currentUser = getCurrentUser();
        // 这里应该更新用户收藏
        log.info("Updating favorite {} for user: {}", favoriteId, currentUser.getId());
    }
    
    /**
     * 删除用户收藏
     */
    @Transactional
    public void deleteUserFavorite(Integer favoriteId) {
        UserDetailsImpl currentUser = getCurrentUser();
        // 这里应该删除用户收藏
        log.info("Deleting favorite {} for user: {}", favoriteId, currentUser.getId());
    }
    
    /**
     * 检查用户是否存在
     */
    public boolean userExists(String username) {
        return userRepository.existsByNickName(username);
    }
    
    /**
     * 验证Token
     */
    public boolean validateToken(String token) {
        return jwtUtils.validateToken(token);
    }
    
    /**
     * 从Token获取用户信息
     */
    public User getUserFromToken(String token) {
        String username = jwtUtils.getUsernameFromToken(token);
        return userRepository.findByNickName(username)
            .orElseThrow(() -> new BadCredentialsException("用户不存在"));
    }
    
    /**
     * 获取当前用户
     */
    private UserDetailsImpl getCurrentUser() {
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        if (authentication == null || !(authentication.getPrincipal() instanceof UserDetailsImpl)) {
            throw new IllegalArgumentException("用户未认证");
        }
        return (UserDetailsImpl) authentication.getPrincipal();
    }
}